home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
dev
/
cross
/
GBDK-2.0.lha
/
GBDK
/
lib
/
drawing.s
< prev
next >
Wrap
Text File
|
1998-11-26
|
9KB
|
671 lines
.include "global.s"
.globl .init_vram
.globl .copy_vram
.SOLID = 0x00
.OR = 0x01
.XOR = 0x02
.AND = 0x03
.area _HEADER (ABS)
.org .MODE_TABLE+4*.G_MODE
JP .gmode
.module Drawing
.area _CODE
;; Enter graphic mode
.gmode::
DI ; Disable interrupts
;; Turn the screen off
LDH A,(.LCDC)
BIT 7,A
JR Z,1$
;; Turn the screen off
CALL .display_off
1$:
LD HL,#0x8000+0x10*0x10
LD DE,#0x1800-0x18*0x10
LD B,#0x00
CALL .init_vram ; Init the charset at 0x8000
;; Install interrupt routines
LD BC,#.vbl
CALL .add_VBL
LD BC,#.lcd
CALL .add_LCD
LD A,#72 ; Set line at which LCD interrupt occurs
LDH (.LYC),A
LD A,#0b01000100 ; Set LCD interrupt to occur when LY = LCY
LDH (.STAT),A
LDH A,(.IE)
OR #0b00000010 ; Enable LCD interrupt
LDH (.IE),A
;; (9*20) = 180 tiles are used in the upper part of the screen
;; (9*20) = 180 tiles are used in the lower part of the screen
;; => We have 24 tiles free
;; We keep 16 at 0x8000->0x80FF, and 8 at 0x9780->97FF
LD HL,#0x9800
LD A,#0x10 ; Keep 16 tiles free
LD BC,#12 ; 12 unused columns
LD E,#18 ; 18 lines
2$:
LD D,#20 ; 20 used columns
3$:
LD (HL+),A
INC A
DEC D
JR NZ,3$
ADD HL,BC
DEC E
JR NZ,2$
;; Turn the screen on
LDH A,(.LCDC)
OR #0b10010001 ; LCD = On
; BG Chr = 0x8000
; BG = On
AND #0b11110111 ; BG Bank = 0x9800
LDH (.LCDC),A
LD A,#.G_MODE
LD (.mode),A
EI ; Enable interrupts
RET
.vbl::
LDH A,(.LCDC)
OR #0b00010000 ; Set BG Chr to 0x8000
LDH (.LCDC),A
LD A,#72 ; Set line at which LCD interrupt occurs
LDH (.LYC),A
RET
.lcd::
1$:
LDH A,(.STAT)
BIT 1,A
JR NZ,1$
LDH A,(.LCDC)
AND #0b11101111 ; Set BG Chr to 0x8800
LDH (.LCDC),A
RET
;; Draw a full-screen image at (BC)
.draw_image::
LD HL,#0x8000+0x10*0x10
LD DE,#0x1680
CALL .copy_vram ; Move the charset
RET
;; Replace tile data at (B,C) with data at DE and store old value at HL
.switch_data::
PUSH DE ; Save src
PUSH HL ; Save dst
LD DE,#0x8000+0x10*0x10
LD L,B
SLA L
SLA L
SLA L
LD H,#0x00
ADD HL,HL
ADD HL,DE
LD D,H
LD E,L
LD HL,#.y_table
SLA C
SLA C
SLA C
LD B,#0x00
ADD HL,BC
ADD HL,BC
LD B,(HL)
INC HL
LD H,(HL)
LD L,B
ADD HL,DE
LD B,H ; BC = src
LD C,L
POP HL ; HL = dst
PUSH BC ; Save dst
LD A,H
OR L
JR Z,1$
LD DE,#0x10
CALL .copy_vram
1$:
POP HL ; HL = dst
POP BC ; BC = src
LD DE,#0x10
CALL .copy_vram
RET
;; Draw a point at (B,C) with color D and mode E
.plot::
PUSH DE ; Save color and mode
LD DE,#0x8000+0x10*0x10
LD A,B
LD L,B
SRL L
SRL L
SRL L
RLC L
RLC L
RLC L
LD H,#0x00
ADD HL,HL
ADD HL,DE
LD D,H
LD E,L
LD HL,#.y_table
LD B,#0x00
ADD HL,BC
ADD HL,BC
LD B,(HL)
INC HL
LD H,(HL)
LD L,B
ADD HL,DE
AND #7
ADD #0x10 ; Table of bits is located at 0x0010
LD E,A
LD D,#0x00
LD A,(DE)
LD B,A
CPL
LD C,A
POP DE ; Restore color and mode
LD A,E
CP #.SOLID
JR NZ,10$
;; Solid
1$:
LDH A,(.STAT)
BIT 1,A
JR NZ,1$
LD A,(HL)
AND C
BIT 0,D
JR Z,2$
OR B
2$:
LD (HL+),A
3$:
LDH A,(.STAT)
BIT 1,A
JR NZ,3$
LD A,(HL)
AND C
BIT 1,D
JR Z,4$
OR B
4$:
LD (HL),A
RET
10$:
CP #.XOR
JR NZ,20$
;; Xor
BIT 0,D
JR Z,12$
11$:
LDH A,(.STAT)
BIT 1,A
JR NZ,11$
LD A,(HL)
XOR B
LD (HL+),A
12$:
BIT 1,D
RET Z
13$:
LDH A,(.STAT)
BIT 1,A
JR NZ,13$
LD A,(HL)
XOR B
LD (HL),A
RET
20$:
CP #.OR
JR NZ,30$
;; Or
BIT 0,D
JR Z,22$
21$:
LDH A,(.STAT)
BIT 1,A
JR NZ,21$
LD A,(HL)
OR B
LD (HL+),A
22$:
BIT 1,D
RET Z
23$:
LDH A,(.STAT)
BIT 1,A
JR NZ,23$
LD A,(HL)
OR B
LD (HL),A
RET
30$:
CP #.AND
RET NZ
;; And
BIT 0,D
JR NZ,32$
31$:
LDH A,(.STAT)
BIT 1,A
JR NZ,31$
LD A,(HL)
AND C
LD (HL+),A
32$:
BIT 1,D
RET NZ
33$:
LDH A,(.STAT)
BIT 1,A
JR NZ,33$
LD A,(HL)
AND C
LD (HL),A
RET
;; ************************************************************
;; Draw a line from x1,y1 (B,C) to x2,y2 (D,E) with color H and mode L
;
; BC: current point
.area _BSS
.a_diff:
.ds 0x01
.a_xy:
.ds 0x01
.sx:
.ds 0x01
.sy:
.ds 0x01
.line_color:
.ds 0x01
.line_mode:
.ds 0x01
.area _CODE
.line:
LD A,H
LD (.line_color),A
LD A,L
LD (.line_mode),A
; ax = ABS(x2-x1)<<1; sx = SGN(x2-x1);
;
LD A,D
SUB B ; A=x2-x1
JR C,1$
; x2-x1 >= 0
; A=ABS(x2-x1)
LD H,A ; Backup ABS(x2-x1) in H
LD A,#0x01 ; A=SGN(x2-x1)=1
JR 2$
1$: ; x2-x1 < 0
CPL ; A=ABS(x2-x1)
INC A
LD H,A ; Backup ABS(x2-x1) in H
LD A,#0xFF ; A=SGN(x2-x1)=-1
2$:
LD (.sx),A
; ay = ABS(y2-y1)<<1; sy = SGN(y2-y1);
;
LD A,E
SUB C ; A=y2-y1
JR C,3$
; y2-y1 >= 0
; A=ABS(y2-y1)
LD L,A ; Backup ABS(y2-y1) in L
LD A,#0x01 ; A=SGN(y2-y1)=1
JR 4$
3$: ; y2-y1 < 0
CPL ; A=ABS(y2-y1)
INC A
LD L,A ; Backup ABS(y2-y1) in L
LD A,#0xFF ; A=SGN(y2-y1)=-1
4$:
LD (.sy),A
; if(ax>ay)
;
LD A,L
SUB H ; A=ay>>1-ax>>1
JR NC,7$
; ax>ay (x dominant)
LD A,H
SUB L ; A=ax>>1-ay>>1
ADD A
LD (.a_diff),A ; a_diff=ax-ay
LD A,L
ADD A
LD (.a_xy),A ; a_xy=ay
; d = (ay<<1)-ax;
;
LD A,L
ADD A
SUB H ; A=ay-(ax>>1)=(ay<<1)-ax=(L<<1)-H
LD L,A ; HL=d
LD A,#0x00
SBC A
LD H,A
; for(;;)
;
5$:
; plot(x,y);
;
CALL .line_plot
; if(x==x2) return;
;
LD A,D
CP B
RET Z
; if(d>=0)
;
LD A,H
AND #0x80
JR NZ,6$
; d>=0
; x+=sx;
;
LD A,(.sx)
ADD B
LD B,A
; y+=sy;
;
LD A,(.sy)
ADD C
LD C,A
; d-=(ax-ay);
;
LD A,(.a_diff)
LD H,A
LD A,L
SUB H
LD L,A
LD A,#0x00
SBC A
LD H,A
JR 5$
6$: ; d<0
; x+=sx;
;
LD A,(.sx)
ADD B
LD B,A
; d+=ay;
;
LD A,(.a_xy)
ADD L
LD L,A
LD A,H
ADC #0x00
LD H,A
JR 5$
7$: ; ax<=ay (y dominant)
ADD A
LD (.a_diff),A ; a_diff=ay-ax
LD A,H
ADD A
LD (.a_xy),A ; a_xy=ax
; d = (ax<<1)-ay;
;
LD A,H
ADD A
SUB L ; A=(ax<<1)-ay=ax-(ay>>1)=(H<<1)-L
LD L,A ; HL=d
LD A,#0x00
SBC A
LD H,A
; for(;;)
;
8$:
; plot(x,y);
;
CALL .line_plot
; if(y==y2) return;
;
LD A,E
CP C
RET Z
; if(d>=0)
;
LD A,H
AND #0x80
JR NZ,9$
; d>=0
; x+=sx;
;
LD A,(.sx)
ADD B
LD B,A
; y+=sy;
;
LD A,(.sy)
ADD C
LD C,A
; d-=(ay-ax);
;
LD A,(.a_diff)
LD H,A
LD A,L
SUB H
LD L,A
LD A,#0x00
SBC A
LD H,A
JR 8$
9$: ; d<0
; y+=sy;
;
LD A,(.sy)
ADD C
LD C,A
; d+=ax;
;
LD A,(.a_xy)
ADD L
LD L,A
LD A,H
ADC #0x00
LD H,A
JR 8$
;; ************************************************************
;; Plot a point at (B,C)
;; Save registers
;
.line_plot:
PUSH BC
PUSH DE
PUSH HL
LD A,(.line_color)
LD D,A
LD A,(.line_mode)
LD E,A
CALL .plot
POP HL
POP DE
POP BC
RET
_plot::
PUSH BC
LD A,(.mode)
CP #.G_MODE
JR Z,1$
CALL .gmode
1$:
LDA HL,4(SP) ; Skip return address and registers
LD B,(HL) ; B = x
INC HL
LD C,(HL) ; C = y
INC HL
LD D,(HL) ; D = color
INC HL
LD E,(HL) ; E = mode
CALL .plot
POP BC
RET
_switch_data::
PUSH BC
LD A,(.mode)
CP #.G_MODE
JR Z,1$
CALL .gmode
1$:
LDA HL,4(SP) ; Skip return address and registers
LD B,(HL) ; B = x
INC HL
LD C,(HL) ; C = y
INC HL
LD E,(HL) ; DE = src
INC HL
LD D,(HL)
INC HL
LD A,(HL+) ; HL = dst
LD H,(HL)
LD L,A
CALL .switch_data
POP BC
RET
_line::
PUSH BC
LD A,(.mode)
CP #.G_MODE
JR Z,1$
CALL .gmode
1$:
LDA HL,4(SP) ; Skip return address and registers
LD B,(HL) ; B = x1
INC HL
LD C,(HL) ; C = y1
INC HL
LD D,(HL) ; D = x2
INC HL
LD E,(HL) ; E = y2
INC HL
LD A,(HL+) ; H = color
LD L,(HL) ; L = mode
LD H,A
CALL .line
POP BC
RET
_draw_image::
PUSH BC
LD A,(.mode)
CP #.G_MODE
JR Z,1$
CALL .gmode
1$:
LDA HL,4(SP) ; Skip return address and registers
LD C,(HL) ; HL = data
INC HL
LD B,(HL)
CALL .draw_image
POP BC
RET
_clear:: ; Clear the graphics screen
LD HL,#0x8000+0x10*0x10
LD DE,#0x1680
1$:
LDH A,(.STAT)
AND #0x02
JR NZ,1$
LD (HL+),A ; A is already zero
DEC DE
LD A,D
OR E
JR NZ,1$
RET
.area _DATA
.y_table::
.word 0x0000,0x0002,0x0004,0x0006,0x0008,0x000A
.word 0x000C,0x000E,0x0140,0x0142,0x0144,0x0146
.word 0x0148,0x014A,0x014C,0x014E,0x0280,0x0282
.word 0x0284,0x0286,0x0288,0x028A,0x028C,0x028E
.word 0x03C0,0x03C2,0x03C4,0x03C6,0x03C8,0x03CA
.word 0x03CC,0x03CE,0x0500,0x0502,0x0504,0x0506
.word 0x0508,0x050A,0x050C,0x050E,0x0640,0x0642
.word 0x0644,0x0646,0x0648,0x064A,0x064C,0x064E
.word 0x0780,0x0782,0x0784,0x0786,0x0788,0x078A
.word 0x078C,0x078E,0x08C0,0x08C2,0x08C4,0x08C6
.word 0x08C8,0x08CA,0x08CC,0x08CE,0x0A00,0x0A02
.word 0x0A04,0x0A06,0x0A08,0x0A0A,0x0A0C,0x0A0E
.word 0x0B40,0x0B42,0x0B44,0x0B46,0x0B48,0x0B4A
.word 0x0B4C,0x0B4E,0x0C80,0x0C82,0x0C84,0x0C86
.word 0x0C88,0x0C8A,0x0C8C,0x0C8E,0x0DC0,0x0DC2
.word 0x0DC4,0x0DC6,0x0DC8,0x0DCA,0x0DCC,0x0DCE
.word 0x0F00,0x0F02,0x0F04,0x0F06,0x0F08,0x0F0A
.word 0x0F0C,0x0F0E,0x1040,0x1042,0x1044,0x1046
.word 0x1048,0x104A,0x104C,0x104E,0x1180,0x1182
.word 0x1184,0x1186,0x1188,0x118A,0x118C,0x118E
.word 0x12C0,0x12C2,0x12C4,0x12C6,0x12C8,0x12CA
.word 0x12CC,0x12CE,0x1400,0x1402,0x1404,0x1406
.word 0x1408,0x140A,0x140C,0x140E,0x1540,0x1542
.word 0x1544,0x1546,0x1548,0x154A,0x154C,0x154E